#pragma once

#include <string>
#include <glm/glm.hpp>
#include "engine/platform/resource_manager.h"
#include "engine/renderer/anim/sprite_sheet.h"
#include "engine/utils/timer.h"
#include "engine/renderer/mesh/elipse.h"

namespace kanon
{
    class Actor;
    class Component 
    {
    public:
        Actor* owner;
    public:
        ~Component() {}
        virtual void Update(float dt) {}
    };

#if 0
    class Mesh2DComponent : public Component
    {
    public:
        virtual glm::vec4 BoundBox() const { return glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); }
    };
#endif

    class Collider2DComponent : public Component
    {
    public:
        glm::vec4 bbox;
        Collider2DComponent(const glm::vec4& box) { this->bbox = box; }
        Collider2DComponent(const glm::vec2& tl, const glm::vec2& br)
        {
            this->bbox = glm::vec4(tl.x, tl.y, br.x, br.y);
        }
    };

    class Transform2DComponent : public Component
    {
    public:
        glm::vec2 position;
        float rotation = 0.0f;
        float scale = 1.0f;

        Transform2DComponent(const glm::vec2& pos, float rot, float s)
            : position(pos), rotation(rot), scale(s) {}
    };

    class Physics2DComponent : public Component
    {
    public:
        glm::vec2 speed;
        float mass = 1.0f;
        bool isStatic = false;

        Physics2DComponent(const glm::vec2& vel, float m, bool stat)
            : speed(vel), mass(m), isStatic(stat) {}

        void Update(float dt) override;
    };

    // sprite2d 
    class SpriteMeshComponent : public Component
    {
    public:
        glm::vec2 size;
        SpriteMeshComponent(const glm::vec2& size)
            : size(size) {}
    };

    class Render2DComponent : public Component
    {
    public:
        glm::vec4 color;
        std::shared_ptr<Texture2D> texture;
        glm::vec4 texture_coords;

        Render2DComponent(const glm::vec4& c)
            : color(c) 
        {
            texture = nullptr;
            texture_coords = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
        }

        Render2DComponent(const std::shared_ptr<Texture2D>& tex)
        {
            texture = tex;
            color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
            texture_coords = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
        }

        Render2DComponent(const std::shared_ptr<Texture2D>& tex, const glm::vec4& uv)
        {
            texture = tex;
            color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
            texture_coords = uv;
        }
    };

    class SpriteAnimationComponent : public Component
    {
    public:
        float fps;
        glm::vec4 uvs;
        std::shared_ptr<SpriteSheet> sheet;
        uint32_t index = 0;
        std::shared_ptr<PeriodicUpdater> updater;

        SpriteAnimationComponent(const std::shared_ptr<SpriteSheet>& sheet, float fps);

        void Update(float deltaTime);
    };

    // circle
    class CircleMeshComponent : public Component
    {
    public:
        glm::vec2 radius;
    public:
        CircleMeshComponent(const glm::vec2& radius) { this->radius = radius; }
        CircleMeshComponent(float radius) { this->radius = glm::vec2(radius, radius); }
    };

    class CircleRenderComponent : public Component
    {
    public:
        glm::vec4 color;
    public:
        CircleRenderComponent(const glm::vec4& color) { this->color = color; }
    };

};
